package org.millioncall.yueyoga.common.security;

import java.util.Date;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import nl.captcha.Captcha;

import org.millioncall.openplatform.util.CaptchaUtils;
import org.millioncall.openplatform.util.WebAppUtils;
import org.millioncall.yueyoga.admin.model.LoginUser;
import org.millioncall.yueyoga.admin.service.UserService;
import org.millioncall.yueyoga.admin.service.impl.UserServiceImpl.LoginResult;
import org.millioncall.yueyoga.common.GlobalConstants;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.stereotype.Controller;

@Controller
public class ZhuwUsernamePasswordAuthenticationFilter extends
		UsernamePasswordAuthenticationFilter {

	private UserService userService;

	@Override
	public Authentication attemptAuthentication(HttpServletRequest request,
			HttpServletResponse response) throws AuthenticationException {
		if (!request.getMethod().equals("POST")) {// 非post提交，不予受理
			throw new AuthenticationServiceException(
					"Authentication method not supported: "
							+ request.getMethod());
		}
		// 通过request，取得用户提交认证信息
		String username = obtainUsername(request);
		String password = obtainPassword(request);
		String organization = obtainOrganization(request);
		//String captcha = obtainCaptcha(request);
		String sessionCaptcha = null;
//		try {
//			sessionCaptcha = obtainSessionCaptcha(request);
//		} catch (Exception e) {
//			throw new AuthenticationServiceException("生成验证码失败，请关闭浏览器后重试");
//		}
		String loginIp = obtainClientIp(request);
		// 构造一个登录用户对象
		LoginUser lu = new LoginUser();
		lu.setUsername(username);
		lu.setPassword(password);
		lu.setOrganization(organization);
		//lu.setCaptcha(captcha);
		lu.setLoginTime(new Date());// 设置登录时间
		lu.setLoginIp(loginIp);
		// 使用UserService类对登录用户对象进行登录认证
		LoginResult lr = userService.userLogin(lu, sessionCaptcha);
		if (!lr.isSuccess()) {// 认证失败
			throw new AuthenticationServiceException(lr.getResultMsg());// 抛出异常，则跳转到simpleUrlAuthenticationFailureHandler指定的defaultFailureUrl
		}

		request.getSession().setAttribute(GlobalConstants.LOGIN_USER_KEY,
				lr.getUser());// 将数据库用户信息设置到session中

		UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(
				username, password);
		setDetails(request, authRequest);// 存储用户的详细信息，userDetailsService中认证时会用到
		return this.getAuthenticationManager().authenticate(authRequest);// 调用UserDetailsService返回认证用户对象
	}

	// 取得表单提交的用户名
	@Override
	protected String obtainUsername(HttpServletRequest request) {
		return request.getParameter("user.username");
	}

	// 取得表单提交的密码
	@Override
	protected String obtainPassword(HttpServletRequest request) {
		return request.getParameter("user.password");
	}

	// 取得表单提交的机构编号
	protected String obtainOrganization(HttpServletRequest request) {
		return request.getParameter("user.organization");
	}

	// 取得表单提交的验证码
	protected String obtainCaptcha(HttpServletRequest request) {
		return request.getParameter("user.captcha");
	}

	// 取得session中的验证码
	protected String obtainSessionCaptcha(HttpServletRequest request) {
		HttpSession session = request.getSession();
		Captcha capt = (Captcha) session
				.getAttribute(CaptchaUtils.WEBAPP_CAPTCHA_KEY);
		if (capt == null) {
			throw new RuntimeException("生成验证码异常");
		}
		return capt.getAnswer();
	}

	// 取得客户端ip地址
	protected String obtainClientIp(HttpServletRequest request) {
		return WebAppUtils.getClientIp(request);
	}

	public UserService getUserService() {
		return userService;
	}

	public void setUserService(UserService userService) {
		this.userService = userService;
	}

}